// Copyright 2024 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import Typography from '@mui/material/Typography';
import { Fragment } from 'react';

import CLList from '@/clusters/components/cl_list/cl_list';
import { ExoneratedTestVariantBranch } from '@/clusters/hooks/use_fetch_exonerated_test_variant_branches';
import {
  TestStabilityCriteria,
  TestVariantStabilityAnalysis_FlakeRate_VerdictExample,
} from '@/proto/go.chromium.org/luci/analysis/proto/v1/test_variants.pb';

import { ExplanationChip } from '../explanation_chip/explanation_chip';
import InvocationList from '../invocations_list/invocations_list';

interface Props {
  criteria: TestStabilityCriteria;
  testVariantBranch: ExoneratedTestVariantBranch;
}

const FlakyCriteriaSection = ({ criteria, testVariantBranch }: Props) => {
  const chips = [];
  if (criteria.flakeRate?.flakeRateThreshold) {
    chips.push(
      <ExplanationChip
        displayValue={`${testVariantBranch.flakeRate.runFlakyVerdicts} / ${testVariantBranch.flakeRate.totalVerdicts}`}
        value={
          testVariantBranch.flakeRate.runFlakyVerdicts /
          testVariantBranch.flakeRate.totalVerdicts
        }
        threshold={criteria.flakeRate.flakeRateThreshold}
        text="Run-flaky source verdict rate (7 day)"
        testId="flaky_verdicts_rate_7d"
      />,
    );
  }
  if (criteria.flakeRate?.flakeThreshold) {
    chips.push(
      <ExplanationChip
        value={testVariantBranch.flakeRate.runFlakyVerdicts}
        threshold={criteria.flakeRate.flakeThreshold}
        text="Run-flaky source verdicts (7 day)"
        testId="flaky_verdicts_7d"
      />,
    );
  }
  return (
    <>
      <Typography variant="h6">Purpose</Typography>
      <Typography paragraph>
        Exonerates test variants that are so flaky that (inexpensive) retries
        are no longer effective at mitigating failures.
      </Typography>
      <Typography variant="h6">Definition</Typography>
      <Typography component="div" paragraph>
        {chips.map((chip, i) => {
          return (
            <Fragment key={`chip-${i}`}>
              {i > 0 ? <>&nbsp;AND&nbsp;</> : null}
              {chip}
            </Fragment>
          );
        })}
        &nbsp;.
      </Typography>
      <Typography component="div">
        Where:
        <ul>
          <li>
            <strong>Source verdict</strong>: The final test result outcome for a
            set of code sources under test, considering all in-build and
            cross-build retries. A source verdict is said to be run-flaky if it
            required a step-level (i.e. swarming task-level) retry to obtain an
            expected test result. Counts are filtered to:
            <ul>
              <li>
                at most one source verdict per distinct changelist tested (to
                avoid a single repeatedly retried bad changelist becoming
                overrepresented),
              </li>
              <li>
                exclude source verdicts that include changelists generated by
                automation (e.g. autorollers), and
              </li>
              <li>
                exclude results from certain unusual CI processes, such as
                multi-changelist presubmit.
              </li>
            </ul>
          </li>
          <li>
            <strong>Sources under test</strong>: The combination of the base git
            commit tested and the (optional) gerrit changelist applied.
          </li>
        </ul>
      </Typography>
      {testVariantBranch.flakeRate &&
        testVariantBranch.flakeRate?.flakeExamples.length > 0 && (
          <>
            <Typography variant="h6">
              Recent run-flaky source verdicts
            </Typography>
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell>Commit Position</TableCell>
                  <TableCell>Changelist and patchset</TableCell>
                  <TableCell>Invocation(s)</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {testVariantBranch.flakeRate?.flakeExamples.map(
                  (
                    verdict: TestVariantStabilityAnalysis_FlakeRate_VerdictExample,
                  ) => {
                    return (
                      <TableRow key={verdict.invocations[0]}>
                        <TableCell>{verdict.position}</TableCell>
                        <TableCell>
                          <CLList
                            changelists={verdict.changelists || []}
                          ></CLList>
                        </TableCell>
                        <TableCell>
                          <InvocationList
                            testId={testVariantBranch.testId}
                            invocations={verdict.invocations}
                          />
                        </TableCell>
                      </TableRow>
                    );
                  },
                )}
              </TableBody>
            </Table>
          </>
        )}
    </>
  );
};

export default FlakyCriteriaSection;
